<?php
namespace App\Services\Infra;

use App\Models\Device;
use App\Models\DeviceInfo;
use App\Models\WxUserDevice;
use App\Models\WxUser;
use App\Exceptions\DeviceException;
use DB;
use Exception;

class DeviceManager
{

	/**
	 * 增加用户绑定设备记录
	 * @param object $wxUser     WxUser 对象
	 * @param string $deviceCode 设备编码
	 */
	public function add($wxUser, $deviceCode)
	{
		try{
			$device = $this->getDeviceByDeviceCode($deviceCode);
			if(is_null($device))
			{
				$device = Device::create(['code' => $deviceCode]);
			}

			$result = WxUserDevice::where('user_id', $wxUser->user_id)->where('device_id', $device->id)->first();
			if(is_null($result))
			{
	    		WxUserDevice::create([
	    				'user_id' => $wxUser->user_id,
	    				'device_id' => $device->id,
	    			]);
			}
		}catch(Exception $e){
			throw new DeviceException('bind');
		}
	}

	/**
	 * 用户解绑， 删除对应绑定记录
	 * @param object $user       WxUser 对象
	 * @param string $deviceCode 设备编码
	 */
	public function deleteByUserDeviceCode($user, $deviceCode){
		$device = $this->getDeviceByDeviceCode($deviceCode);
		if(!is_null($device))
		{

			WxUserDevice::where('device_id', $device->id)->delete();
		}
	}

	/**
	 * @param  WxUser   $user
	 * @return array 	设备号列表
	 */
	public function getDeviceListByUser($user){
		$user->load(['devices' => function($query){
			$query->select(['id', 'code']);
		}]);
		return $user->devices;
	}

    /**
     * @param  WxUser   $wxUser
     * @param  string 	设备号
     */
    public function isBound($wxUser, $deviceCode)
    {
    	$device = $this->getDeviceByDeviceCode($deviceCode);
    	if(is_null($device))
    	{
    		throw new DeviceException('noBind');
    	}
    	
    	$record = WxUserDevice::where('user_id', $wxUser->user_id)->where('device_id', $device->id)->first();
    	if(is_null($record))
    	{
    		throw new DeviceException('noBind');
    	}
    }

    /**
     * 更新
     * @param  [type] $userId   
     * @param  [type] $deviceId 
     * @param  [type] $data     
     * @return [type]           
     */
    public function updateWxDevice($userId, $deviceId, $data)
    {
    	WxUserDevice::where('user_id', $userId)->where('device_id', $deviceId)->update($data);
    }

    /**
     * 是否生成记录
     * @param  [type]  $deviceCode 
     * @return boolean             
     */
    public function isCreateDeviceRecord($deviceCode)
    {
    	$device = $this->getDeviceByDeviceCode($deviceCode);
    	if(is_null($device))
    	{
    		Device::create(['code' => $deviceCode]);
    	}
    }

    /**
     * 根据设备码获取设备
     * @param  [type] $deviceCode 
     * @return [type]             
     */
    public function getDeviceByDeviceCode($deviceCode)
    {
    	return Device::where('code', $deviceCode)->first();
    }

    /**
     * 获取正常的设备的最新的记录
     * @param  [type] $deviceId 
     * @return [type] 
     */
    public function getNormalLatestRecordByDeviceId($deviceId)
    {
    	return DeviceInfo::where('device_id', $deviceId)->where('dec_status', '!=', Device::HYDROPENIA)->where('dec_status', '!=', Device::OVERHAUL)->latest()->first();
    }

    /**
     * 保存设备信息
     * @param  [type] $data 
     * @return [type]       
     */
    public function save($data)
    {
    	$device = $this->getDeviceByDeviceCode($data['device_code']);
    	$record = $this->getNormalLatestRecordByDeviceId($device->id);
    	if(is_null($record))
    	{
    		$dailyWaterConsumption = $data['water_cnt'];
    	}
    	else
    	{
    		$dailyWaterConsumption = $data['water_cnt'] - $record->water_cnt;
            $dailyWaterConsumption <= 0 ? 0 : $dailyWaterConsumption;
    	}
    	$data = array_merge($data, [
    		'device_id' => $device->id,
    		'daily_water_consumption' => $dailyWaterConsumption,
    		]);
    	DeviceInfo::create($data);
    }

    /**
     * 根据状态获取全部设备信息包含设备码
     * @param  [type] $status 
     * @return [type]         
     */
    public function getAllDeviceInfoWithCodeByStatus($status, $deviceCode = null)
    {
        $ids = DB::select('select max(id) from (select * from device_infos as b order by b.created_at desc) as a group by a.device_id');

        $query = DeviceInfo::with('device');
        if(!empty($status) && ($status == Device::HYDROPENIA || $status == Device::OVERHAUL))
        {
            $query->where('dec_status', $status);
        }
        if(!is_null($deviceCode))
        {
            $deviceIds = Device::where('code', 'like', '%'.$deviceCode.'%')->select('id')->get();
            $query->whereIn('device_id', $deviceIds);
        }

        return $query->whereIn('id', $ids)->groupBy('device_id')->select([
                                                                        'device_id',
                                                                        'filter_cnt2',
                                                                        'filter_cnt1',
                                                                        'daily_water_consumption',
                                                                        'water_cnt',
                                                                        'dec_status',
                                                                        'created_at',
                                                                        ]);
    }

    public function getAllDeviceInfoWithCodeByDeviceCode($deviceId)
    {
        return DeviceInfo::where('device_id', $deviceId)->select([
                                                            'device_id',
                                                            'filter_cnt1',
                                                            'filter_cnt2',
                                                            'daily_water_consumption',
                                                            'water_cnt',
                                                            'dec_status',
                                                            'created_at',
                                                            ])->latest();
    }

}